{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第六章：卷积神经网络\n",
    "湖北理工学院《机器学习》课程资料\n",
    "\n",
    "作者：李辉楚吴\n",
    "\n",
    "笔记内容概述: 卷积神经网络、手写字母识别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test set size: 10000\n",
      "Training set size: 60000\n",
      "Number of training samples: 43360\n",
      "Number of cross-validation samples: 10850\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "import torchvision.transforms as transforms\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "label_size = 18 # Label size\n",
    "ticklabel_size = 14 # Tick label size\n",
    "    \n",
    "# Define a transform to normalize the data\n",
    "transform = transforms.Compose([\n",
    "    transforms.ToTensor()\n",
    "])\n",
    "\n",
    "# Load test data from the MNIST\n",
    "testset = torchvision.datasets.MNIST(root='./Data', train=False, download=False, transform=transform)\n",
    "print(f\"Test set size: {len(testset)}\")\n",
    "\n",
    "# Load training data from the MNIST\n",
    "trainset = torchvision.datasets.MNIST(root='./Data', train=True, download=False, transform=transform)\n",
    "print(f\"Training set size: {len(trainset)}\")\n",
    "\n",
    "# Rate of trX and cvX\n",
    "tr_cv_rate = 0.8\n",
    "\n",
    "# Create a list to store indices for each class unique()\n",
    "class_indices = [[] for _ in range(10)]  # 10 classes in MNIST\n",
    "\n",
    "# Populate class_indices\n",
    "for idx, (_, label) in enumerate(trainset):\n",
    "    class_indices[label].append(idx)\n",
    "\n",
    "# Calculate the number of samples for each class in training and validation sets\n",
    "train_size_per_class = int(tr_cv_rate * min(len(indices) for indices in class_indices))\n",
    "val_size_per_class = min(len(indices) for indices in class_indices) - train_size_per_class\n",
    "\n",
    "# Create balanced train and validation sets\n",
    "train_indices = []\n",
    "val_indices = []\n",
    "for indices in class_indices:\n",
    "    train_indices.extend(indices[:train_size_per_class])\n",
    "    val_indices.extend(indices[train_size_per_class:train_size_per_class + val_size_per_class])\n",
    "\n",
    "# Create Subset datasets\n",
    "from torch.utils.data import Subset\n",
    "trX = Subset(trainset, train_indices)\n",
    "cvX = Subset(trainset, val_indices)\n",
    "\n",
    "print(f\"Number of training samples: {len(trX)}\")\n",
    "print(f\"Number of cross-validation samples: {len(cvX)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构建DataLoaders，准备训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "image_channels is 1\n",
      "tensor([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 1., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 1., 0., 0., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 1., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],\n",
      "        [1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])\n"
     ]
    }
   ],
   "source": [
    "batch_size = 42 # Define training batch 1，\n",
    "\n",
    "def one_hot_collate(batch):\n",
    "    data = torch.stack([item[0] for item in batch])\n",
    "    labels = torch.tensor([item[1] for item in batch])\n",
    "    one_hot_labels = torch.zeros(labels.size(0), 10)  # 10 classes in MNIST 【0，1，0，0】\n",
    "    one_hot_labels.scatter_(1, labels.unsqueeze(1), 1)\n",
    "    return data, one_hot_labels\n",
    "\n",
    "trLoader = torch.utils.data.DataLoader(trX, batch_size=batch_size, shuffle=True, num_workers=0, collate_fn=one_hot_collate)\n",
    "cvLoader = torch.utils.data.DataLoader(cvX, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "teLoader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=0, collate_fn=one_hot_collate)\n",
    "\n",
    "# Get a batch of training data\n",
    "dataiter = iter(trLoader)\n",
    "data, labels = next(dataiter)\n",
    "\n",
    "image_channels = data[0].numpy().shape[0]\n",
    "print(f'image_channels is {image_channels}')\n",
    "print(labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义并训练卷积神经网络\n",
    "* 输入：2-D图片\n",
    "* 输出：手写字母类型的概率分布\n",
    "* 卷积层：2层, 卷积核大小：3x3\n",
    "* 隐藏层1：100个节点\n",
    "* 隐藏层2：50个节点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN(\n",
      "  (conv1): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "  (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      "  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
      "  (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
      "  (fc1): Linear(in_features=3136, out_features=100, bias=True)\n",
      "  (fc2): Linear(in_features=100, out_features=10, bias=True)\n",
      "  (softmax): Softmax(dim=1)\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "\n",
    "class CNN(nn.Module):\n",
    "    def __init__(self, image_channels, num_classes):\n",
    "        super(CNN, self).__init__()\n",
    "        \n",
    "        # First convolutional layer\n",
    "        self.conv1 = nn.Conv2d(in_channels=image_channels, out_channels=32, kernel_size=3, padding=1)\n",
    "        self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        \n",
    "        # Second convolutional layer\n",
    "        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n",
    "        self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        \n",
    "        # Fully connected layers\n",
    "        self.fc1 = nn.Linear(64 * 7 * 7, 100)  # After two 2x2 max pools, 28x28 -> 7x7\n",
    "        self.fc2 = nn.Linear(100, num_classes)  # 10 classes output\n",
    "\n",
    "        # Softmax\n",
    "        self.softmax = nn.Softmax(dim=1)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # Remove the reshape operation and directly use x\n",
    "        x = F.relu(self.conv1(x))\n",
    "        x = self.pool1(x)\n",
    "        \n",
    "        # Second conv layer\n",
    "        x = F.relu(self.conv2(x))\n",
    "        x = self.pool2(x)\n",
    "        \n",
    "        # Flatten the output for the fully connected layers\n",
    "        x = x.view(-1, 64 * 7 * 7)\n",
    "        \n",
    "        # Fully connected layers\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "        \n",
    "        # Softmax\n",
    "        x = self.softmax(x)\n",
    "        \n",
    "        return x\n",
    "\n",
    "# Initialize the model\n",
    "model = CNN(image_channels, 10)\n",
    "if torch.cuda.is_available():\n",
    "    model = model.cuda()\n",
    "\n",
    "# Display model architecture\n",
    "print(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用Adam作为Optimizor训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/50], Train Loss: 1.5611, CV Loss: 1.4983\n",
      "Epoch [2/50], Train Loss: 1.4885, CV Loss: 1.4868\n",
      "Epoch [3/50], Train Loss: 1.4808, CV Loss: 1.4861\n",
      "Epoch [4/50], Train Loss: 1.4778, CV Loss: 1.4844\n",
      "Epoch [5/50], Train Loss: 1.4754, CV Loss: 1.4832\n",
      "Epoch [6/50], Train Loss: 1.4748, CV Loss: 1.4820\n",
      "Epoch [7/50], Train Loss: 1.4727, CV Loss: 1.4823\n",
      "Epoch [8/50], Train Loss: 1.4724, CV Loss: 1.4851\n",
      "Epoch [9/50], Train Loss: 1.4709, CV Loss: 1.4806\n",
      "Epoch [10/50], Train Loss: 1.4702, CV Loss: 1.4764\n",
      "Epoch [11/50], Train Loss: 1.4692, CV Loss: 1.4797\n",
      "Epoch [12/50], Train Loss: 1.4686, CV Loss: 1.4737\n",
      "Epoch [13/50], Train Loss: 1.4686, CV Loss: 1.4773\n",
      "Epoch [14/50], Train Loss: 1.4679, CV Loss: 1.4814\n",
      "Epoch [15/50], Train Loss: 1.4683, CV Loss: 1.4794\n",
      "Epoch [16/50], Train Loss: 1.4678, CV Loss: 1.4763\n",
      "Epoch [17/50], Train Loss: 1.4679, CV Loss: 1.4760\n",
      "Epoch [18/50], Train Loss: 1.4670, CV Loss: 1.4814\n",
      "Epoch [19/50], Train Loss: 1.4678, CV Loss: 1.4765\n",
      "Epoch [20/50], Train Loss: 1.4659, CV Loss: 1.4782\n",
      "Epoch [21/50], Train Loss: 1.4674, CV Loss: 1.4782\n",
      "Epoch [22/50], Train Loss: 1.4662, CV Loss: 1.4778\n",
      "Epoch [23/50], Train Loss: 1.4662, CV Loss: 1.4757\n",
      "Epoch [24/50], Train Loss: 1.4660, CV Loss: 1.4754\n",
      "Epoch [25/50], Train Loss: 1.4659, CV Loss: 1.4756\n",
      "Epoch [26/50], Train Loss: 1.4660, CV Loss: 1.4744\n",
      "Epoch [27/50], Train Loss: 1.4654, CV Loss: 1.4760\n",
      "Epoch [28/50], Train Loss: 1.4660, CV Loss: 1.4763\n",
      "Epoch [29/50], Train Loss: 1.4656, CV Loss: 1.4748\n",
      "Epoch [30/50], Train Loss: 1.4653, CV Loss: 1.4801\n",
      "Epoch [31/50], Train Loss: 1.4658, CV Loss: 1.4773\n",
      "Epoch [32/50], Train Loss: 1.4655, CV Loss: 1.4803\n",
      "Epoch [33/50], Train Loss: 1.4653, CV Loss: 1.4748\n",
      "Epoch [34/50], Train Loss: 1.4648, CV Loss: 1.4746\n",
      "Epoch [35/50], Train Loss: 1.4641, CV Loss: 1.4759\n",
      "Epoch [36/50], Train Loss: 1.4651, CV Loss: 1.4784\n",
      "Epoch [37/50], Train Loss: 1.4645, CV Loss: 1.4763\n",
      "Epoch [38/50], Train Loss: 1.4663, CV Loss: 1.4765\n",
      "Epoch [39/50], Train Loss: 1.4649, CV Loss: 1.4758\n",
      "Epoch [40/50], Train Loss: 1.4657, CV Loss: 1.4744\n",
      "Epoch [41/50], Train Loss: 1.4644, CV Loss: 1.4751\n",
      "Epoch [42/50], Train Loss: 1.4653, CV Loss: 1.4760\n",
      "Epoch [43/50], Train Loss: 1.4649, CV Loss: 1.4755\n",
      "Epoch [44/50], Train Loss: 1.4645, CV Loss: 1.4794\n",
      "Epoch [45/50], Train Loss: 1.4645, CV Loss: 1.4756\n",
      "Epoch [46/50], Train Loss: 1.4650, CV Loss: 1.4759\n",
      "Epoch [47/50], Train Loss: 1.4653, CV Loss: 1.4744\n",
      "Epoch [48/50], Train Loss: 1.4650, CV Loss: 1.4739\n",
      "Epoch [49/50], Train Loss: 1.4650, CV Loss: 1.4744\n",
      "Epoch [50/50], Train Loss: 1.4645, CV Loss: 1.4755\n"
     ]
    }
   ],
   "source": [
    "# Define loss function and optimizer\n",
    "criterion = nn.CrossEntropyLoss() # Loss\n",
    "optimizer = torch.optim.Adam(model.parameters()) # Adam\n",
    "\n",
    "# Lists to store losses\n",
    "train_losses = []\n",
    "cv_losses = []\n",
    "\n",
    "# Number of epochs\n",
    "num_epochs = 50\n",
    "\n",
    "for epoch in range(num_epochs):\n",
    "    model.train()\n",
    "    batch_losses = []\n",
    "    \n",
    "    for batch_x, batch_y in trLoader:\n",
    "        # Forward pass\n",
    "        outputs = model(batch_x)\n",
    "        loss = criterion(outputs, batch_y)\n",
    "        \n",
    "        # Backward pass and optimize\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        \n",
    "        batch_losses.append(loss.item())\n",
    "    \n",
    "    # Calculate average training loss for this epoch\n",
    "    avg_train_loss = sum(batch_losses) / len(batch_losses)\n",
    "    train_losses.append(avg_train_loss)\n",
    "    \n",
    "    # Evaluate on cross-validation set\n",
    "    model.eval()\n",
    "    cv_batch_losses = []\n",
    "    with torch.no_grad():\n",
    "        for cv_x, cv_y in cvLoader:\n",
    "            cv_outputs = model(cv_x)\n",
    "            cv_loss = criterion(cv_outputs, cv_y)\n",
    "            cv_batch_losses.append(cv_loss.item())\n",
    "    \n",
    "    avg_cv_loss = sum(cv_batch_losses) / len(cv_batch_losses)\n",
    "    cv_losses.append(avg_cv_loss)\n",
    "    \n",
    "    print(f'Epoch [{epoch+1}/{num_epochs}], Train Loss: {avg_train_loss:.4f}, CV Loss: {avg_cv_loss:.4f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "计算识别精度，展示学习曲线"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accuracy on training set: 99.68%\n",
      "Accuracy on cross-validation set: 98.53%\n"
     ]
    },
    {
     "data": {
      "image/png": "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09NTGjJkiHTixAnz/qtXr0oTJkyQGjduLLm5uUnu7u5SixYtpM8//9xcFXHPnj3SAw88IIWFhUlqtVqqU6eO1K1bN+mPP/4o13uRJEnS6XSSv79/qZXrJKlq59mt55MkSdLly5el4cOHW5wTu3fvLvF8puO8vb0ljUYj9evXTzp+/LgUFhYmjR8/3uI558yZI0VEREgKhcLieUr7vebn50uvv/66FBYWJimVSikwMFB65plnpBs3blgcV96/kbIAKPNiOifT0tKkp59+WgoMDJScnJyksLAwacqUKVJBQYH5ef7880+pf//+Ur169SSVSiX5+flJAwYMkHbt2mU+Zvbs2VKnTp2kunXrSiqVSgoNDZUmTpwoxcfH37GdRFS7ySTpprEaRERU68yYMQNvv/02EhISEBwcbOvmEBER1VocFkhEVIt8/fXXAIDGjRtDr9dj69at+PLLL/Hwww8zWBEREVUzhisiolrE1dUVn3/+OeLj46HVahEaGorXX38db7/9tq2bRkREVOtxWCAREREREZEVsBQ7ERERERGRFTBcERERERERWQHDFRERERERkRWwoEUpjEYjrly5Ao1GA5lMZuvmEBERERGRjUiShOzsbAQFBUEuv33fFMNVKa5cuYKQkBBbN4OIiIiIiOxEYmLiHZc1YbgqhUajASB+gB4eHjZuDRERERER2UpWVhZCQkLMGeF2GK5KYRoK6OHhwXBFRERERETlmi7EghZERERERERWwHBFRERERERkBQxXREREREREVsA5V0RERER3OUmSUFhYCIPBYOumENmEUqmEQqGo8vMwXBERERHdxXQ6HZKTk5GXl2frphDZjEwmQ3BwMNzd3av0PAxXRERERHcpo9GIuLg4KBQKBAUFQaVSlasiGlFtIkkSrl27hsuXLyMyMrJKPVgMV0RERER3KZ1OB6PRiJCQELi6utq6OUQ24+vri/j4eOj1+iqFKxa0ICIiIrrLyeX8SEh3N2v12PIviYiIiIiIyAoYroiIiIiIiKyA4YqIiIiI7nrdu3fHSy+9VO7j4+PjIZPJEBsbW21tIsfDcEVEREREDkMmk932MmHChEo976pVq/DBBx+U+/iQkBAkJyejWbNmlXq98mKIcyysFkhEREREDiM5Odl8e9myZXj33Xdx5swZ8zYXFxeL4/V6PZRK5R2f18fHp0LtUCgU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RERERES2Uqlw9fHHH+O///0vunfvjtGjR6Nly5YAgD/++MM8XJBqjqmgBXuuiIiIiIhsx6kyD+revTuuX7+OrKwseHt7m7c/+eSTcHV1tVrjqHw0pkWEGa6IiIiIiGymUj1X+fn50Gq15mB16dIlzJkzB2fOnIGfn59VG0h3xoIWRERERES2V6lwNWTIECxatAgAkJGRgfbt22P27NkYOnQo5s6da9UG0p253xSujEbJxq0hIiIiIro7VSpcHTp0CF26dAEArFixAv7+/rh06RIWLVqEL7/80qoNpDszFbQAgFwde6+IiIiIiGyhUuEqLy8PGo0GALBx40YMGzYMcrkcHTp0wKVLl6zaQLoztZMcSoUMAIcGEhERERHZSqXCVcOGDbFmzRokJiZiw4YN6NOnDwAgNTUVHh4eVm0g3ZlMJisux86iFkRERERENlGpcPXuu+/ilVdeQXh4OO6991507NgRgOjFat26tVUbSOVjLsfOnisiIiIiIpuoVCn2ESNG4L777kNycrJ5jSsAiImJwQMPPGC1xlH5uauVAPLZc0VEREREZCOVClcAEBAQgICAAFy+fBkymQz16tXjAsI2pFGzHDsRERERkS1Valig0WjE+++/D09PT4SFhSE0NBReXl744IMPYDQard1GKgdzOXb2XBERERER2USleq7eeust/Pjjj/joo4/QuXNnSJKEf/75B9OmTUNBQQGmT59u7XbSHZgKWnDOFRERERGRbVQqXP3000/44YcfcP/995u3tWzZEvXq1cOzzz7LcGUD7LkiIiIiIrKtSg0LTE9PR+PGjUtsb9y4MdLT06vcKKq44jlXehu3hIiIiIjo7lSpcNWyZUt8/fXXJbZ//fXXaNGiRZUbRRXnzoIWREREREQ2ValhgbNmzcLAgQOxefNmdOzYETKZDLt370ZiYiLWrVtn7TZSOZjXueKwQCIiIiIim6hUz1W3bt1w9uxZPPDAA8jIyEB6ejqGDRuGEydOYMGCBdZuI5UDe66IiIiIiGyr0utcBQUFlShcceTIEfz000+YP39+lRtGFaNhQQsiIiIiIpuqVM8V2R93tRIAe66IiIiIiGyF4aqW4JwrIiIiIiLbYriqJTjnioiIiIjItio052rYsGG33Z+RkVGVtlAVmOdcaQshSRJkMpmNW0REREREdHepULjy9PS84/5x48ZVqUFUOaaeK4NRQr7eAFdVpWuVEBERERFRJVToEzjLrNsvV5UCchlglETFQIYrIiIiIqKaxTlXtYRMJjP3XmVz3hURERERUY1juKpFNM5F5dhZMZCIiIiIqMYxXNUirBhIRERERGQ7DFe1CNe6IiIiIiKyHYarWoQ9V0REREREtsNwVYuYeq5yCvQ2bgkRERER0d2H4aoW0bDnioiIiIjIZhiuahGWYiciIiIish2Gq1qkeFggwxURERERUU1juKpFWNCCiIiIiMh2GK5qEQ17roiIiIiIbIbhqhZxVysBcM4VEREREZEtMFzVIpxzRURERERkOwxXtQjnXBERERER2Q7DVS1innPFcEVEREREVOMYrmoRc88VhwUSEREREdU4hqtaxDTnSmcwQltosHFriIiIiIjuLgxXtYibysl8m71XREREREQ1i+GqFlHIZXBTKQBw3hURERERUU1juKplNM5Fa12x54qIiIiIqEYxXNUypnlXDFdERERERDWL4aqW4VpXRERERES2wXBVyxSvdaW3cUuIiIiIiO4uDFe1DNe6IiIiIiKyDZuGq507d2Lw4MEICgqCTCbDmjVrbnv89u3bIZPJSlxOnz5tcdzKlSvRtGlTqNVqNG3aFKtXr67Gd2FfTOEqm8MCiYiIiIhqlE3DVW5uLlq2bImvv/66Qo87c+YMkpOTzZfIyEjzvj179mDkyJF45JFHcOTIETzyyCN46KGH8O+//1q7+XbJVNCCPVdERERERDXL6c6HVJ/+/fujf//+FX6cn58fvLy8St03Z84c9O7dG1OmTAEATJkyBTt27MCcOXOwZMmSqjTXIWhY0IKIiIiIyCYccs5V69atERgYiJiYGGzbts1i3549e9CnTx+LbX379sXu3bvLfD6tVousrCyLi6NizxURERERkW04VLgKDAzEvHnzsHLlSqxatQpRUVGIiYnBzp07zcekpKTA39/f4nH+/v5ISUkp83lnzpwJT09P8yUkJKTa3kN1c1cXLSLMnisiIiIiohpl02GBFRUVFYWoqCjz/Y4dOyIxMRGffvopunbtat4uk8ksHidJUoltN5syZQomT55svp+VleWwAYs9V0REREREtuFQPVel6dChA86dO2e+HxAQUKKXKjU1tURv1s3UajU8PDwsLo6Kc66IiIiIiGzD4cPV4cOHERgYaL7fsWNHbNq0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JCTg6aeftnXTyM7k5OTg/Pnz5vtxcXGIjY2Fj48PQkND8dJLL2HGjBmIjIxEZGQkZsyYAVdXV4wZM8aGrSZ7MGnSJPz666/4/fffodFozN/0eXp6wsXFxbzuDM8fKs2bb76J/v37IyQkBNnZ2Vi6dCm2b9+O9evX89yh29JoNOa5nSZubm6oU6eOeTvPHyrLK6+8gsGDByM0NBSpqan48MMPkZWVhfHjxzvuvz02q1N4l/nmm2+ksLAwSaVSSW3atDGXRya62bZt2yQAJS7jx4+XJEmUJZ06daoUEBAgqdVqqWvXrtKxY8ds22iyC6WdNwCkBQsWmI/h+UNleeyxx8z/R/n6+koxMTHSxo0bzft57lBF3FyKXZJ4/lDZRo4cKQUGBkpKpVIKCgqShg0bJp04ccK83xHPHZkkSZKNch0REREREVGtwTlXREREREREVsBwRUREREREZAUMV0RERERERFbAcEVERERERGQFDFdERERERERWwHBFRERERERkBQxXREREREREVsBwRUREREREZAUMV0RERFYmk8mwZs0aWzeDiIhqGMMVERHVKhMmTIBMJitx6devn62bRkREtZyTrRtARERkbf369cOCBQsstqnVahu1hoiI7hbsuSIiolpHrVYjICDA4uLt7Q1ADNmbO3cu+vfvDxcXF0RERGD58uUWjz927Bh69uwJFxcX1KlTB08++SRycnIsjpk/fz6io6OhVqsRGBiI5557zmL/9evX8cADD8DV1RWRkZH4448/qvdNExGRzTFcERHRXeedd97B8OHDceTIETz88MMYPXo0Tp06BQDIy8tDv3794O3tjf3792P58uXYvHmzRXiaO3cuJk2ahCeffBLHjh3DH3/8gYYNG1q8xnvvvYeHHnoIR48exYABAzB27Fikp6fX6PskIqKaJZMkSbJ1I4iIiKxlwoQJWLx4MZydnS22v/7663jnnXcgk8nw9NNPY+7cueZ9HTp0QJs2bfDtt9/i+++/x+uvv47ExES4ubkBANatW4fBgwfjypUr8Pf3R7169fDoo4/iww8/LLUNMtn/27l/l+SiOI7j7ys5qNwlpHJrqnCoxQapJZzaAtsiXCOQFsdAod3+AkchaGgLHRyFcHKr/gGJGkOoxZ7hAUF6eH5xn57S92s695x7D+eMH8753oDT01POzs4AGA6HhGHI9fW1tV+SNMWsuZIkTZ2dnZ2J8AQwPz8/bufz+YmxfD5Pv98H4Pb2lo2NjXGwAtja2mI0GnF/f08QBAwGAwqFwk/XsL6+Pm6nUinCMOTx8fFvtyRJ+gIMV5KkqZNKpd5d0/uVIAgAeHt7G7d/9E4ikfit+eLx+LtvR6PRH61JkvS1WHMlSZo5Nzc3757X1tYAyGaz9Pt9hsPheLzb7RKLxVhZWSEMQ5aXl+l0Oh+6ZknS5+fJlSRp6ry+vvLw8DDRNzc3RzqdBuDy8pJcLsf29jbNZpNer0ej0QDg4OCAarVKqVSiVqvx9PREuVzm8PCQxcVFAGq1GkdHRywsLLC7u8vz8zPdbpdyufyxG5UkfSqGK0nS1Gm1WmQymYm+1dVV7u7ugO9/8ru4uOD4+JilpSWazSbZbBaAZDJJu93m5OSEzc1NkskkxWKRer0+nqtUKvHy8sL5+TmVSoV0Os3+/v7HbVCS9Cn5t0BJ0kwJgoCrqyv29vb+91IkSVPGmitJkiRJioDhSpIkSZIiYM2VJGmmeBtekvSveHIlSZIkSREwXEmSJElSBAxXkiRJkhQBw5UkSZIkRcBwJUmSJEkRMFxJkiRJUgQMV5IkSZIUAcOVJEmSJEXgGyjGVeAvF0F2AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Calculate and print accuracies for training and cross-validation sets\n",
    "model.eval()\n",
    "with torch.no_grad():\n",
    "    # Training set accuracy\n",
    "    tr_correct = 0\n",
    "    tr_total = 0\n",
    "    for images, labels in trLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        tr_total += labels.size(0)\n",
    "        tr_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    tr_accuracy = 100 * tr_correct / tr_total\n",
    "    \n",
    "    # Test set accuracy\n",
    "    cv_correct = 0\n",
    "    cv_total = 0\n",
    "    for images, labels in cvLoader:\n",
    "        outputs = model(images)\n",
    "        _, predicted = torch.max(outputs, 1)\n",
    "        _, true_labels = torch.max(labels, 1)\n",
    "        cv_total += labels.size(0)\n",
    "        cv_correct += (predicted == true_labels).sum().item()\n",
    "    \n",
    "    cv_accuracy = 100 * cv_correct / cv_total\n",
    "\n",
    "print(f'Accuracy on training set: {tr_accuracy:.2f}%')\n",
    "print(f'Accuracy on cross-validation set: {cv_accuracy:.2f}%')\n",
    "\n",
    "# Plot training and cross-validation losses\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(range(1, num_epochs+1), train_losses, label='Training Loss')\n",
    "plt.plot(range(1, num_epochs+1), cv_losses, label='Cross-Validation Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Training and Cross-Validation Loss')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
